//
//  showVideoViewController.m
//  FFmpeg_X264_Codec
//
//  Created by 陆永亨 on 16/1/8.
//  Copyright © 2016年 suntongmian@163.com. All rights reserved.
//

#import "showVideoViewController.h"
#import "VideoDecoder.h"
#import "colorconvert.h"
#import "UIView+Frame.h"
#import <stdlib.h>
#import "GCDAsyncSocket.h"
#import "udpSocket.h"
#import "NativeFileManager.h"
enum playStatus
{
    isStop = 101,
    isPause,
    isRunning
};

@interface showVideoViewController ()
{
    int m_playStatus;
     GCDAsyncSocket *socket;
    udpSocket * m_udpSocket;
    NativeFileManager * m_navtiveFilemanager;
}

@property (strong,nonatomic)UIImageView * videoView;
@property(strong,nonatomic)NSTimer * timer;
@end

@implementation showVideoViewController


int mTrans=0x0F0F0F0F;

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

-(void)clickbarkItem
{
    m_playStatus = isStop;
    if (self.timer.isValid) {
        [self.timer invalidate];
    }
    self.timer=nil;
    [self dismissViewControllerAnimated:YES completion:nil];
}
-(void)clickRightItem
{
    [self start:nil];
}

-(void)clickSendItem
{
    //[self start:nil];
    [self submitContentButtonClick];
}
- (void)viewDidLoad
{
    [super viewDidLoad];
      [self connectToServer];
    // Do any additional setup after loading the view, typically from a nib.
    self.title = _videoPath?_videoPath:@"";
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIBarButtonItem * item = [[UIBarButtonItem alloc]initWithTitle:@"返回" style:UIBarButtonItemStyleDone target:self action:@selector(clickbarkItem)];
    self.navigationItem.leftBarButtonItem = item;
    
    UIBarButtonItem * item1 = [[UIBarButtonItem alloc]initWithTitle:@"播放" style:UIBarButtonItemStyleDone target:self action:@selector(clickRightItem)];
    self.navigationItem.rightBarButtonItem = item1;
    UIBarButtonItem * item2 = [[UIBarButtonItem alloc]initWithTitle:@"发送" style:UIBarButtonItemStyleDone target:self action:@selector(clickSendItem)];
    NSArray * aryitem = @[item1,item2];
    self.navigationItem.rightBarButtonItems =aryitem;
    _videoView = [[UIImageView alloc]init];
    _videoView.contentMode = UIViewContentModeScaleAspectFit;
    _videoView.frame = CGRectMake(5,70, SCREEN_WIDTH-10, SCREEN_HEIGHT-NAVIGATION_BAR_HEIGHT-TAB_BAR_HEIGHT);
    // _videoView.backgroundColor =  [UIColor colorWithRed:255/255.0 green:70/255.0 blue:183/255.0 alpha:1];
    [self.view addSubview:self.videoView];
    m_navtiveFilemanager = [[NativeFileManager alloc]init];
    
    
}

#pragma mark - sockt
-(void)connectToServer
{
//    socket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
//    NSError *err;
//    [socket connectToHost:@"192.168.0.106" onPort:8889 error:&err];
//    if (err != nil) {
//        NSLog(@"%@",err);
//    }
//
    m_udpSocket = [[udpSocket alloc]init];
    char * address = "192.168.0.106";
    int port = 8556;
    [m_udpSocket createUdpByIpAddr:address andPort:port];
    
    
    
    if (self.timer) {
           [self.timer invalidate];
              self.timer = nil;
          }
    
 
    
   [NSThread detachNewThreadSelector:@selector(vodise) toTarget:self withObject:nil];
    
}

-(void)vodise
{
   
    
    NSLog(@"Test timer shedult to a non-running runloop");
 
    NSTimer *timer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:1] interval:0.1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    // 打开下面一行输出runloop的内容就可以看出，timer却是已经被添加进去
    NSLog(@"the thread's runloop: %@", [NSRunLoop currentRunLoop]);
    
    // 打开下面一行, 该线程的runloop就会运行起来，timer才会起作用
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
    
   
}

-(void)timerAction
{
    [m_udpSocket recvData:2048];
    NSLogGreen(@"2");

}

-(void)submitContentButtonClick
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    if (!_videoPath) {
        return;
    }
    
    NSString *FilePath = [documentsDirectory stringByAppendingPathComponent:_videoPath];
    [m_navtiveFilemanager createFileManager:[FilePath UTF8String]];
    
    NSData *data2 = [[NSData alloc]initWithContentsOfFile:FilePath];
    
//    if ([socket isConnected]) {
//        [socket writeData:data2 withTimeout:5 tag:2];
//    }
//    else
//        NSLogGreen(@"sockt 未连接");
   
     int a_len ;
    
    char * video_buff;
    int totol_len =0;
    while (1)
    {
        
        video_buff = [m_navtiveFilemanager readFileData:(int)data2.length andReadSize:&a_len];
      
        if (video_buff==NULL)
        {
            break;
        }
         totol_len+=a_len;
        
        char *video_buff_tmp = video_buff ;
   
        int remain_len = 0;

        int video_buff_tmp_len;
        
        if (a_len>1400)
        {
        
            do
            {
                video_buff_tmp_len =  [m_udpSocket sendData:video_buff_tmp andSize:1400];
                
                remain_len = a_len - 1400;
                video_buff_tmp=video_buff_tmp+1400;
                NSLogGreen(@"do-%d",video_buff_tmp_len);
               
            } while (remain_len > 1400);
        
            video_buff_tmp_len = [m_udpSocket sendData:video_buff_tmp andSize:remain_len];
            NSLogGreen(@"while-%d",video_buff_tmp_len);
        }
        else
        {
            video_buff_tmp_len = [m_udpSocket sendData:video_buff andSize:a_len];
            NSLogGreen(@"else-%d",video_buff_tmp_len);
        }

   
    
    }
    NSLogGreen(@"%d",totol_len);
     [m_navtiveFilemanager closeFileManager];

}

-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
    NSLog(@"%@",host);
    
    //    NSString *response  = [NSString stringWithFormat:@"iam:%@", @"xubaobao"];
    //    NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
    //    [socket writeData:data  withTimeout:5 tag:1];
    //
    //
    //    NSString *response2 = [NSString stringWithFormat:@"msg:%@",@"i Love you"];
    //    NSData *data2 = [[NSData alloc]initWithData:[response2 dataUsingEncoding:NSASCIIStringEncoding]];
    //    [socket writeData:data2 withTimeout:5 tag:2];
    //设置连接一直不超时
    [socket readDataWithTimeout:-1 tag:0];
}
//完成写之后调用
-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    uint8_t buffer[1024];
    int len;
    NSInputStream *writeStream = (NSInputStream *)socket.writeStream;
    while ([writeStream hasBytesAvailable]) {
        //获取长度
        len = (int)[writeStream read:buffer maxLength:sizeof(buffer)];
        if (len > 0) {
            //转化成string
            NSString *output = [[NSString alloc]initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];;
            if (nil != output) {
                NSLog(@"server said: %@", output);
                
            }
        }
    }
}
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    NSString *outPutStr = [[NSString alloc]initWithData:data encoding:NSASCIIStringEncoding];
    NSLog(@"%@",outPutStr);
    
    
}

#pragma mark - 解码
-(void)decodeAndShow : (char*) pFrameRGB length:(int)len nWidth:(int)nWidth nHeight:(int)nHeight
{
    
    
    //NSLog(@"decode ret = %d readLen = %d\n", ret, nFrameLen);
    if(len > 0)
    {
        CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
        CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, pFrameRGB, nWidth*nHeight*3,kCFAllocatorNull);
        CGDataProviderRef provider = CGDataProviderCreateWithCFData(data);
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        
        CGImageRef cgImage = CGImageCreate(nWidth,
                                           nHeight,
                                           8,
                                           24,
                                           nWidth*3,
                                           colorSpace,
                                           bitmapInfo,
                                           provider,
                                           NULL,
                                           YES,
                                           kCGRenderingIntentDefault);
        CGColorSpaceRelease(colorSpace);
        //UIImage *image = [UIImage imageWithCGImage:cgImage];
        UIImage* image = [[UIImage alloc]initWithCGImage:cgImage];   //crespo modify 20111020
        CGImageRelease(cgImage);
        CGDataProviderRelease(provider);
        CFRelease(data);
        [self performSelectorOnMainThread:@selector(updateView:) withObject:image waitUntilDone:YES];
        //[image release];
    }
    
    return;
}

-(void)updateView:(UIImage*)newImage
{
    NSLog(@"显示新画面");
    //VideoView.image = newImage;
    self.videoView.image = newImage;
}
#warning 解码！！！
- (void)decode:(id)sender
{
    NSLog(@"start");
    
//    NSString *bundlePath = [[NSBundle mainBundle] resourcePath];
//    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//    NSString *docDir = [paths objectAtIndex:0];
    // NSLog(bundlePath);
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    if (!_videoPath) {
        return;
    }
    
    NSString *FilePath = [documentsDirectory stringByAppendingPathComponent:_videoPath];
    // NSLog(FilePath);
    
    FILE *_imgFileHandle =NULL;
    
    _imgFileHandle =fopen([FilePath UTF8String],"rb");
    
    if (_imgFileHandle != NULL)
    {
        NSLog(@"File Exist");
        void* handle = VideoDecoder_Init();
        int iTemp=0;
        int nalLen;
        int bytesRead = 0;
        int NalBufUsed=0;
        int SockBufUsed=0;
        
        bool bFirst=true;
        bool bFindPPS=true;
        
        char  SockBuf[2048];
        char  NalBuf[40980]; // 40k
        //char  buffOut[115200];
        
        char *buffOut = (char *)malloc(sizeof(char)*720*1280*3/2);
        
        
        
        char *rgbBuffer = (char *)malloc(sizeof(char)*720*1280*3);
        int outSize, nWidth, nHeight;
        outSize = 1382400;
        memset(SockBuf,0,2048);
        memset(buffOut,0,1382400);
        InitConvtTbl();
        do {
            bytesRead = fread(SockBuf, 1, 2048, _imgFileHandle);
            NSLog(@"bytesRead  = %d", bytesRead);
            if (bytesRead<=0) {
                break;
            }
            SockBufUsed = 0;
            while (bytesRead - SockBufUsed > 0) {
                if (m_playStatus == isStop) {
                    break;
                }
                
                if (m_playStatus == isPause) {
                    continue;
                }
                
                nalLen = MergeBuffer(NalBuf, NalBufUsed, SockBuf, SockBufUsed, bytesRead-SockBufUsed);
                NalBufUsed += nalLen;
                SockBufUsed += nalLen;
                
                while(mTrans == 1)
                {
                    mTrans = 0xFFFFFFFF;
                    
                    if(bFirst==true) // the first start flag
                    {
                        bFirst = false;
                    }
                    else  // a complete NAL data, include 0x00000001 trail.
                    {
                        if(bFindPPS==true) // true
                        {
                            if( (NalBuf[4]&0x1F) == 7 )
                            {
                                bFindPPS = false;
                            }
                            else
                            {
                                NalBuf[0]=0;
                                NalBuf[1]=0;
                                NalBuf[2]=0;
                                NalBuf[3]=1;
                                
                                NalBufUsed=4;
                                
                                break;
                            }
                        }
                        
                        //	decode nal
                        iTemp = VideoDecoder_Decode(handle, NalBuf, NalBufUsed, buffOut,  outSize, &nWidth, &nHeight);
                        [NSThread sleepForTimeInterval:0.04];
                        if(iTemp == 0)
                        {
                            i420_to_rgb24(buffOut, rgbBuffer, nWidth, nHeight);
                            flip(rgbBuffer, nWidth, nHeight);
                            [self decodeAndShow:rgbBuffer length:nWidth*nHeight*3 nWidth:nWidth nHeight:nHeight];
                            //nFrameCount++;
                        }
                        else
                        {
                            //Log.e("DecoderNal", "DecoderNal iTemp <= 0");
                        }
                        
                        //if(iTemp>0)
                        //postInvalidate();  //使用postInvalidate可以直接在线程中更新界面    // postInvalidate();
                    }
                    
                    NalBuf[0]=0;
                    NalBuf[1]=0;
                    NalBuf[2]=0;
                    NalBuf[3]=1;
                    
                    NalBufUsed=4;
                }
            }
            
            //int nRet = VideoDecoder_Decode(handle, buff, nReadBytes, buffOut,  outSize, &nWidth, &nHeight);
            NSLog(@"nDecodeRet = %d  nWidth = %d  nHeight = %d", iTemp, nWidth, nHeight);
        } while (bytesRead>0);
       
        free(buffOut);
        free(rgbBuffer);
        fclose(_imgFileHandle);
        VideoDecoder_UnInit(handle);
        //self.videoView = nil;
        self.videoView.image = nil;
    }
    
}
-(void)start:(id)sender
{
    if (m_playStatus ==isRunning) {
        return;
    }
    m_playStatus = isRunning;
    [NSThread detachNewThreadSelector:@selector(decode:) toTarget:self withObject:nil];
    
}




int MergeBuffer(char* NalBuf, int NalBufUsed, char* SockBuf, int SockBufUsed, int SockRemain)
{//把读取的数剧分割成NAL块
    int  i=0;
    char Temp;
    
    for(i=0; i<SockRemain; i++)
    {
        Temp  =SockBuf[i+SockBufUsed];
        NalBuf[i+NalBufUsed]=Temp;
        
        mTrans <<= 8;
        mTrans  |= Temp;
        
        if(mTrans == 1) // 找到一个开始字
        {
            i++;
            break;
        }
    }
    
    return i;
}
void flip(char *pRGBBuffer, int nWidth, int nHeight)
{
    char temp[nWidth*3];
    for (int i = 0; i<nHeight/2; i++) {
        memcpy(temp, pRGBBuffer + i*nWidth*3, nWidth*3);
        memcpy(pRGBBuffer + i*nWidth*3, pRGBBuffer + (nHeight - i - 1)*nWidth*3, nWidth*3);
        memcpy(pRGBBuffer + (nHeight - i - 1)*nWidth*3, temp, nWidth*3);
    }
    /*
     for (int i = 0; i<nHeight/2; i++) {
     memcpy(temp, pRGBBuffer + i*nWidth + nWidth*nHeight, nWidth);
     memcpy(pRGBBuffer + i*nWidth + nWidth*nHeight, pRGBBuffer + (nHeight - i - 1)*nWidth + nWidth*nHeight, nWidth);
     memcpy(pRGBBuffer + (nHeight - i - 1)*nWidth + nWidth*nHeight, temp, nWidth);
     }
     for (int i = 0; i<nHeight/2; i++) {
     memcpy(temp, pRGBBuffer + i*nWidth + nWidth*nHeight*2, nWidth);
     memcpy(pRGBBuffer + i*nWidth + nWidth*nHeight*2, pRGBBuffer + (nHeight - i - 1)*nWidth + nWidth*nHeight*2, nWidth);
     memcpy(pRGBBuffer + (nHeight - i - 1)*nWidth + nWidth*nHeight*2, temp, nWidth);
     }
     */
    
}


@end
